package justweb

// 中间件相关

import (
	"fmt"
	"time"
)

// 通过init注册我们自己默认的中间件
func init() {
	RegisterFilter("timeCost", MetricFilterBuilder)
	RegisterFilter("sayhello", HelloFilterBuilder)
	fmt.Println("默认中间件注册完成")
}

// 中间件数据结构
type FilterBuilder func(next Filter) Filter
type Filter = HandlerFunc

// 维护一个map结构，存放构造中间件的方法，通过名字索引，这样就可以完成映射
type filterMap map[string]FilterBuilder

// type filterMap map[string]*FilterBuilder

// 单例-饿汉模式，直接定义
var fm filterMap = make(filterMap, 5)

// var fm filterMap  -- 使用懒汉模式，需要了再定义，可以加在通过名字构造服务的方法中sync.Once

// 注册自己的中间件
func RegisterFilter(name string, f FilterBuilder) {
	// 懒汉模式
	// if fm == nil {
	// 	var once sync.Once
	// 	once.Do(func() {
	// 		fm = make(filterMap, 4)
	// 	})
	// }

	if _, ok := fm[name]; !ok {
		fmt.Println(name, "中间件注册")
	} else {
		fmt.Println(name, "中间件覆盖")
	}
	fm[name] = f
}

// 查找中间件构建器
func GetFileterBuilder(name string) (f FilterBuilder, ok bool) {
	f, ok = fm[name]
	return
}

// 查找多个中间件 - 确定都存在的时候，才可以使用
func GetMoreFilterBuilders(names ...string) []FilterBuilder {
	bNames := make([]FilterBuilder, 0, len(names))

	for i := 0; i < len(names); i++ {
		if fbuilder, ok := fm[names[i]]; ok {
			bNames = append(bNames, fbuilder)
		} else {
			fmt.Println(names[i], " 局部中间件注册失败")
		}
	}
	return bNames
}

// ========================相关中间件========================

// 打印请求时间的中间件
func MetricFilterBuilder(next Filter) Filter {
	return func(c *Context) {
		startTime := time.Now().UnixNano()
		next(c)
		endTime := time.Now().UnixNano()
		fmt.Printf("the request cost time %d\n", endTime-startTime)
	}
}

func HelloFilterBuilder(next Filter) Filter {
	return func(c *Context) {
		fmt.Println("hello this is part Filter")
		next(c)
	}
}
